package ynu.edu.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ynu.edu.api.client.CartClient;
import ynu.edu.api.client.ItemClient;
import ynu.edu.api.dto.ItemDTO;
import ynu.edu.api.dto.OrderDetailDTO;
import ynu.edu.common.domain.PageDTO;
import ynu.edu.common.domain.R;
import ynu.edu.common.exception.BadRequestException;
import ynu.edu.common.utils.BeanUtils;
import ynu.edu.common.utils.UserContext;
import ynu.edu.order.constans.MQConstants;
import ynu.edu.order.domain.dto.OrderFormDTO;
import ynu.edu.order.domain.po.Order;
import ynu.edu.order.domain.po.OrderDetail;
import ynu.edu.order.domain.vo.OrderDetailVO;
import ynu.edu.order.domain.vo.OrderVO;
import ynu.edu.order.mapper.OrderMapper;
import ynu.edu.order.service.IOrderDetailService;
import ynu.edu.order.service.IOrderService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final IOrderDetailService detailService;
    private final ItemClient itemClient;
    private final CartClient cartClient;
    private final RabbitTemplate rabbitTemplate;

    @Override
    @Transactional
    public Long createOrder(OrderFormDTO orderFormDTO) {
        // 1.订单数据
        Order order = new Order();
        // 1.1.查询商品
        List<OrderDetailDTO> detailDTOS = orderFormDTO.getDetails();
        // 1.2.获取商品id和数量的Map
        Map<Long, Integer> itemNumMap = detailDTOS.stream()
                .collect(Collectors.toMap(OrderDetailDTO::getItemId, OrderDetailDTO::getNum));
        Set<Long> itemIds = itemNumMap.keySet();
        // 1.3.查询商品
        R<List<ItemDTO>> result_items = itemClient.queryItemByIds(itemIds);
        List<ItemDTO> items = result_items != null && result_items.getData() != null ? result_items.getData() : List.of();
        if (items == null || items.size() < itemIds.size()) {
            throw new BadRequestException("商品不存在");
        }
        // 1.4.基于商品价格、购买数量计算商品总价：totalFee
        int total = 0;
        for (ItemDTO item : items) {
            total += item.getPrice() * itemNumMap.get(item.getId());
        }
        order.setTotalFee(total);
        // 1.5.其它属性
        order.setPaymentType(orderFormDTO.getPaymentType());
        order.setUserId(UserContext.getUser());
        order.setStatus(1);
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        // 1.6.将Order写入数据库order表中
        save(order);

        // 2.保存订单详情
        List<OrderDetail> details = buildDetails(order.getId(), items, itemNumMap);
        detailService.saveBatch(details);

//        // 3.清理购物车商品
//        cartClient.deleteCartItemByIds(itemIds);

        // 4.扣减库存
        try {
            R<Boolean> result_stock = itemClient.deductStock(detailDTOS);
            if (result_stock == null || result_stock.getData() == null || !result_stock.getData()) {
                throw new RuntimeException("库存不足！");
            }
        } catch (Exception e) {
            throw new RuntimeException("库存不足！");
        }

        return order.getId();
    }

    @Override
    public void markOrderPaySuccess(Long orderId) {
        // 1.修改订单状态为已支付
        Order order = getById(orderId);
        if (order == null) {
            throw new BadRequestException("订单不存在");
        }
        if (order.getStatus() != 1) {
            throw new BadRequestException("订单状态不正确");
        }
        order.setStatus(2);
        order.setPayTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        // 2. 新增：支付成功后清理购物车
        cleanCartForOrder(orderId);
        log.info("订单{}支付成功", orderId);
    }

    private void cleanCartForOrder(Long orderId) {
        // 获取订单中的商品ID列表
        List<OrderDetail> details = detailService.query()
                .eq("order_id", orderId)
                .list();

        if (!details.isEmpty()) {
            Set<Long> itemIds = details.stream()
                    .map(OrderDetail::getItemId)
                    .collect(Collectors.toSet());

            Long userId = UserContext.getUser();
            log.info("用户id为：{}", userId);
            // 调用购物车服务清理
            cartClient.deleteCartItemByIds(userId,itemIds);
            log.info("订单{}支付成功，已清理用户{}的购物车商品: {}", orderId, userId,itemIds);
        }
    }

    @Override
    @Transactional
    public void cancelOrder(Long orderId) {
        // 1.查询订单
        Order order = getById(orderId);
        if (order == null) {
            throw new BadRequestException("订单不存在");
        }
        if (order.getStatus() != 1) {
            throw new BadRequestException("订单状态不正确，无法取消");
        }
        
        // 2.修改订单状态为已取消
        order.setStatus(5);
        order.setCloseTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);
        
        // 3.恢复库存
        List<OrderDetail> details = detailService.list(
                new LambdaQueryWrapper<OrderDetail>()
                        .eq(OrderDetail::getOrderId, orderId)
        );
        
        List<OrderDetailDTO> detailDTOS = details.stream()
                .map(detail -> {
                    OrderDetailDTO dto = new OrderDetailDTO();
                    dto.setItemId(detail.getItemId());
                    dto.setNum(detail.getNum());
                    return dto;
                })
                .collect(Collectors.toList());
        
        try {
            R<Boolean> result = itemClient.restoreStock(detailDTOS);
            if (result == null || result.getData() == null || !result.getData()) {
                throw new RuntimeException("恢复库存失败");
            }
            log.info("订单{}取消成功，库存已恢复", orderId);
        } catch (Exception e) {
            log.error("恢复库存失败，订单ID: {}", orderId, e);
            throw new RuntimeException("恢复库存失败");
        }
    }

    @Override
    public void confirmOrder(Long orderId) {
        Order order = getById(orderId);
        if (order == null) {
            throw new BadRequestException("订单不存在");
        }
        if (order.getStatus() != 3) {
            throw new BadRequestException("订单状态不正确，无法确认收货");
        }
        
        order.setStatus(4);
        order.setEndTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);
        log.info("订单{}确认收货成功", orderId);
    }

    @Override
    public void applyRefund(Long orderId) {
        Order order = getById(orderId);
        if (order == null) {
            throw new BadRequestException("订单不存在");
        }
        if (order.getStatus() != 4) {
            throw new BadRequestException("订单状态不正确，无法申请退款");
        }
        
        // 这里可以添加退款逻辑，比如调用退款服务
        // 暂时只是记录日志
        log.info("订单{}申请退款", orderId);
    }

    @Override
    public List<OrderDetailVO> queryOrderDetails(Long orderId) {
        List<OrderDetail> details = detailService.list(
                new LambdaQueryWrapper<OrderDetail>()
                        .eq(OrderDetail::getOrderId, orderId)
        );
        return BeanUtils.copyList(details, OrderDetailVO.class);
    }

    /**
     * 查询用户订单列表
     *
     * @param page     页码
     * @param size     页大小
     * @param status   订单状态
     * @return 用户订单列表
     */
    @Override
    public PageDTO<OrderVO> queryUserOrders(Integer page, Integer size, Integer status) {
        // 构建查询条件
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        log.info("用户id为：{}", UserContext.getUser());
        queryWrapper.eq(Order::getUserId, UserContext.getUser());
        
        // 如果指定了状态，添加状态条件
        if (status != null) {
            queryWrapper.eq(Order::getStatus, status);
        }
        
        // 按创建时间倒序排列
        queryWrapper.orderByDesc(Order::getCreateTime);
        
        // 分页查询
        Page<Order> orderPage = page(new Page<>(page, size), queryWrapper);
        
        // 转换为VO
        Page<OrderVO> voPage = new Page<>(orderPage.getCurrent(), orderPage.getSize(), orderPage.getTotal());
        voPage.setRecords(BeanUtils.copyList(orderPage.getRecords(), OrderVO.class));
        
        return PageDTO.of(voPage, OrderVO.class);
    }

    /**
     * 查询所有订单列表
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageDTO<OrderVO> queryAllOrders(Integer page, Integer size) {
        // 构建查询条件
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();

        // 按创建时间倒序排列
        queryWrapper.orderByDesc(Order::getCreateTime);

        // 分页查询
        Page<Order> orderPage = page(new Page<>(page, size), queryWrapper);

        // 转换为VO
        Page<OrderVO> voPage = new Page<>(orderPage.getCurrent(), orderPage.getSize(), orderPage.getTotal());
        voPage.setRecords(BeanUtils.copyList(orderPage.getRecords(), OrderVO.class));

        return PageDTO.of(voPage, OrderVO.class);
    }

    private List<OrderDetail> buildDetails(Long orderId, List<ItemDTO> items, Map<Long, Integer> numMap) {
        List<OrderDetail> details = new ArrayList<>(items.size());
        for (ItemDTO item : items) {
            OrderDetail detail = new OrderDetail();
            detail.setName(item.getName());
            detail.setSpec(item.getSpec());
            detail.setPrice(item.getPrice());
            detail.setNum(numMap.get(item.getId()));
            detail.setItemId(item.getId());
            detail.setImage(item.getImage());
            detail.setOrderId(orderId);
            detail.setCreateTime(LocalDateTime.now());
            detail.setUpdateTime(LocalDateTime.now());
            details.add(detail);
        }
        return details;
    }
}
